/* arm_systick.c */
/*--------------------------------------------------------------------------*
* Author: suyong_yq
* Email : suyong_yq@126.com
*--------------------------------------------------------------------------*/

#include "arm_systick.h"
#include "fsl_device_registers.h"

typedef struct
{
    void (*CallbackFunc)(void);
    volatile uint32_t Counter;
} Systick_Context_T;

static Systick_Context_T g_SystickContextStruct;

void Systick_ConfigTicker(const Systick_Config_T *configPtr)
{
    g_SystickContextStruct.CallbackFunc = (void *)0U;
    g_SystickContextStruct.Counter = 0U;
    
    /* Set core clock as clock source. */
    SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk; 
    /* Set reload value. */
    SysTick->LOAD = configPtr->CoreClkHz / configPtr->TicksPerSecond;
    SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk  /* Enable the Interrupt. */
                   | SysTick_CTRL_ENABLE_Msk;  /* Enable the Systick. */
}

void Systick_DelayTicksBlocking(uint32_t ticks)
{
    g_SystickContextStruct.Counter = ticks;
    while (g_SystickContextStruct.Counter > 0U)
    {}
}

void Systick_InstallCallback(void (*callbackFunc)(void))
{
    g_SystickContextStruct.CallbackFunc = callbackFunc;
}

/* System defined ISR. */
void SysTick_Handler(void)
{
    /* Decrease the counter. */
    if (g_SystickContextStruct.Counter > 0U)
    {
        g_SystickContextStruct.Counter--;
    }
    
    /* Execute the callback function. */
    if (g_SystickContextStruct.CallbackFunc)
    {
        (void)(*(g_SystickContextStruct.CallbackFunc))();
    }
}

/* EOF. */
